package com.hutao.manage.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.hutao.manage.test.TestDto08;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public class WordUtil {
	private static Logger log = Logger.getLogger(WordUtil.class);
	private static final String ENCODING = "UTF-8";
	private static Configuration cfg = new Configuration();
	// 初始化cfg
	static {
		// 设置模板所在文件夹
		// cfg.setClassForTemplateLoading(WordUtil.class, "D://test.ftl");

		 try {
			//cfg.setDirectoryForTemplateLoading(new File("D://test/"));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		cfg.setClassForTemplateLoading(WordUtil.class, "/ftl/");

		// setEncoding这个方法一定要设置国家及其编码，不然在ftl中的中文在生成html后会变成乱码
		cfg.setEncoding(Locale.getDefault(), ENCODING);
		// 设置对象的包装器
		cfg.setObjectWrapper(new DefaultObjectWrapper());
		// 设置异常处理器,这样的话就可以${a.b.c.d}即使没有属性也不会出错
		cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);

	}

	// 获取模板对象
	public static Template getTemplate(String templateFileName) throws IOException {
		return cfg.getTemplate(templateFileName, ENCODING);
	}

//https://www.cnblogs.com/duanrantao/p/9377818.html
	public static File crateFile(Map<String, Object> data, String templateFileName, String outFilePath) {
		Writer out = null;
		File outFile = new File(outFilePath);
		try {
			// 获取模板,并设置编码方式，这个编码必须要与页面中的编码格式一致
			Template template = getTemplate(templateFileName);
			if (!outFile.getParentFile().exists()) {
				outFile.getParentFile().mkdirs();
			}
			out = new OutputStreamWriter(new FileOutputStream(outFile), ENCODING);
			// 处理模版
			template.process(data, out);
			log.info("由模板文件" + templateFileName + "生成" + outFilePath + "成功.");
		} catch (Exception e) {
			log.error("由模板文件" + templateFileName + "生成" + outFilePath + "出错");
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				log.error("关闭Write对象出错", e);
				e.printStackTrace();
			}
		}
		return outFile;
	}

	public static void exportTemplateWord(HttpServletRequest request, HttpServletResponse response,
			Map<String, Object> map, String ftlName, String docName) throws IOException {
		File file = null;
		InputStream fin = null;
		ServletOutputStream out = null;
		try {

			Template freemarkerTemplate = getTemplate(ftlName);
			// 调用工具类的createDoc方法生成Word文档
			file = createDoc(map, freemarkerTemplate);
			fin = new FileInputStream(file);

			response.setCharacterEncoding("utf-8");
			response.setContentType("application/msword");
			// 设置浏览器以下载的方式处理该文件名也可以从浏览器传入
			String fileName = "" + docName + ".doc";
			response.setHeader("Content-Disposition",
					"attachment;filename=".concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));

			out = response.getOutputStream();
			byte[] buffer = new byte[512]; // 缓冲区
			int bytesToRead = -1;
			// 通过循环将读入的Word文件的内容输出到浏览器中
			while ((bytesToRead = fin.read(buffer)) != -1) {
				out.write(buffer, 0, bytesToRead);
			}
		} catch (Exception o) {
			o.printStackTrace();
		} finally {
			if (fin != null)
				fin.close();
			if (out != null)
				out.close();
			if (file != null)
				file.delete(); // 删除临时文件
		}
	}

	private static File createDoc(Map dataMap, Template template) {
		String name = "test.doc";// 临时文件名
		File f = new File(name);
		Template t = template;
		try {
			// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
			Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");
			t.process(dataMap, w);
			w.close();
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new RuntimeException(ex);
		}
		return f;
	}

	// 获得图片的base64码
	public static String getImageBase(String src) throws Exception {
		if (src == null || src == "") {
			return "";
		}
		File file = new File(src);
		if (!file.exists()) {
			return "";
		}
		InputStream in = null;
		byte[] data = null;
		try {
			in = new FileInputStream(file);
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data);
	}

	/**
	 * 使用freemark进行文本换行使用<w:br/>替换文本中/n或者/r/n
	 * 
	 * @param args
	 */

	public static void main(String[] args) {
		try {
			Map<String, Object> data = new HashMap<String, Object>();
		       List<Map<String,Object>> list1 = new ArrayList<Map<String,Object>>();
		       List<Map<String,Object>> list2 = new ArrayList<Map<String,Object>>();
		       List<Map<String,Object>> list3 = new ArrayList<Map<String,Object>>();

		       List<TestDto08> dtos = new ArrayList<TestDto08>() ;
		       TestDto08 dto1 = new TestDto08();
		       dto1.setA1("钣金");
		       dto1.setAa("aa");
		       dto1.setAb("aa");
		       dto1.setAc("aa");
		       dtos.add(dto1);
		       
		       TestDto08 dto3 = new TestDto08();
		       dto3.setA1("钣金");
		       dto3.setAa("bb");
		       dto3.setAb("bb");
		       dto3.setAc("bb");
		       dtos.add(dto3);

		       List<TestDto08> dtos1 = new ArrayList<TestDto08>() ;
		       TestDto08 dto2 = new TestDto08();
		       dto2.setB1("喷漆");
		       dto2.setAa("cc");
		       dto2.setAb("cc");
		       dto2.setAc("cc");
		       dtos1.add(dto2);
		       TestDto08 dto4 = new TestDto08();
		       dto4.setB1("喷漆");
		       dto4.setAa("dd");
		       dto4.setAb("dd");
		       dto4.setAc("dd");
		       dtos1.add(dto4);

		       List<TestDto08> dtos2 = new ArrayList<TestDto08>() ;
		       TestDto08 dto5 = new TestDto08();
		       dto5.setC1("机修");
		       dto5.setAa("ee");
		       dto5.setAb("ee");
		       dto5.setAc("ee");
		       dtos2.add(dto5);
		       
		       TestDto08 dto6 = new TestDto08();
		       dto6.setC1("机修");
		       dto6.setAa("ff");
		       dto6.setAb("ff");
		       dto6.setAc("ff");
		       dtos2.add(dto6);

		     
		       
		 
			    for (int i = 0; i < dtos.size(); i++) { 
			      Map<String,Object> map = new HashMap<String,Object>();
		             map.put("a1", dtos.get(i).getA1());
				     map.put("aa", dtos.get(i).getAa());
				     map.put("ab", dtos.get(i).getAb());
				     map.put("ac", dtos.get(i).getAc());
				     list1.add(map);
		        }
		       for (int i = 0; i < dtos1.size(); i++) {
		           Map<String,Object> map = new HashMap<String,Object>();
		           map.put("a1", dtos1.get(i).getB1());
		           map.put("aa", dtos1.get(i).getAa());
		           map.put("ab", dtos1.get(i).getAb());
		           map.put("ac", dtos1.get(i).getAc());
		           list2.add(map);
		       }
		       for (int i = 0; i < dtos2.size(); i++) {
		           Map<String,Object> map = new HashMap<String,Object>();
		           map.put("a1", dtos2.get(i).getC1());
		           map.put("aa", dtos2.get(i).getAa());
		           map.put("ab", dtos2.get(i).getAb());
		           map.put("ac", dtos2.get(i).getAc());
		           list3.add(map);
		       }
		       data.put("list1", list1);
		       data.put("list2", list2);
		       data.put("list3", list3);
		       
		       
		      Map<String,Object> newMap = new HashMap<>();
		       newMap.put("map", data);
		     
			
			crateFile(newMap, "testMerge.ftl", "D:/199.doc");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}